<template>
	<scroll-view class="vi_steps_scroll" scroll-x @touchmove.stop>
		<view class="vi_steps" :class="mainClass">
			<view class="vi_steps_group" :class="item._state" :style="groupStyle" v-for="(item, index) in inList" :key="index">
				<view class="vi_steps_point" v-if="item._showType=='icon'" :style="pointStyle">
					<view class="vi_steps_point_icon" v-if="custom">
						<text class="vi_steps_font iconfont" :class="item._icon"></text>
					</view>
					<view class="vi_steps_point_icon" v-else>
						<view class="vi_steps_point_iconUp">
							<vi-style-controller
								:type="item._type"
								:color="item._color"
								:textColor="item._textColor"
								:radius="item._radius"
								:plain="item._plain"
								width="2em"
								height="2em"
								:borderWidth="item._plain?setting.borderWidth:''"
								borderBox
								active>
								<text class="iconfont" :class="item._icon"></text>
							</vi-style-controller>
						</view>
						<vi-style-controller
							:color="index<=currStep&&item._plain?'#fff':setting.lineBgColor"
							:radius="item._radius"
							width="2em"
							height="2em"
							active>
						</vi-style-controller>
					</view>
				</view>
				<view class="vi_steps_point" v-else :style="pointStyle">
					<view class="vi_steps_point_text" v-if="custom">
						<text class="vi_steps_font">{{item.index}}</text>
					</view>
					<view class="vi_steps_point_text" v-else>
						<view class="vi_steps_point_textUp">
							<vi-style-controller
								:type="item._type"
								:color="item._color"
								:textColor="item._textColor"
								:radius="item._radius"
								:plain="item._plain"
								width="2em"
								height="2em"
								:borderWidth="item._plain?setting.borderWidth:''"
								active>
								<text>{{item.index}}</text>
							</vi-style-controller>
						</view>
						<vi-style-controller
							:color="index<=currStep&&item._plain?'#fff':setting.lineBgColor"
							:radius="item._radius"
							width="2em"
							height="2em"
							active>
						</vi-style-controller>
					</view>
				</view>
				<view class="vi_steps_title" :class="{'vi_bold':item._titleBold}">{{item.title}}</view>
				<view class="vi_steps_describe">{{item.describe}}</view>
				<view class="vi_steps_line" :style="lineStyle">
					<vi-style-controller v-if="!custom"
						control="background"
						:type="setting.lineType"
						:color="lineColor"
						:width="vertical?setting.lineHeight:'100%'"
						:height="vertical?'100%':setting.lineHeight"
						:active="item._state=='done'"></vi-style-controller>
				</view>
			</view>
		</view>
	</scroll-view>
</template>

<script>
	export default{
		name:"viSteps",
		model:{
			prop:"value",
			event:"input"
		},
		props:{
			dataList:{
				type:[Array,null],
				default:()=>[
					{
						index:1,		//步骤号
						title:"",		//标题
						describe:"",	//描述
						current:true,	//指示为当前步骤
						defaultIcon:"",	//默认状态显示的图标
						doneIcon:"",	//完成状态显示的图标
						currentIcon:"",	//当前状态显示的图标
					}
				]
			},
			value:{
				type:[Number,String,null],
				default:0
			},
			//是否垂直类型
			vertical:{
				type:[Boolean,null],
				default:false
			},
			//使用css自定义风格，样式由custom.scss定义
			custom:{
				type:[String,null],
				default:""
			},
			//内容对齐，标题与描述位于轴线的哪一侧。before，after，across(水平模式)。使用custom后无效
			alignment:{
				type:[String,null],
				default:""
			},
			radius:{
				type:[String,Number,null],
				default:""
			},
			plain:{
				type:[Boolean,null],
				default:false
			},
			titleBold:{
				type:[Boolean,null],
				default:false
			},
			defaultType:{
				type:[String,null],
				default:""
			},
			defaultColor:{
				type:[String,null],
				default:""
			},
			defaultTextColor:{
				type:[String,null],
				default:""
			},
			defaultTitleColor:{
				type:[String,null],
				default:""
			},
			defaultDescribeColor:{
				type:[String,null],
				default:""
			},
			currentType:{
				type:[String,null],
				default:""
			},
			currentColor:{
				type:[String,null],
				default:""
			},
			currentTextColor:{
				type:[String,null],
				default:""
			},
			currentTitleColor:{
				type:[String,null],
				default:""
			},
			currentDescribeColor:{
				type:[String,null],
				default:""
			},
			lineType:{
				type:[String,null],
				default:""
			},
			lineColor:{
				type:[String,null],
				default:""
			},
			lineBgColor:{
				type:[String,null],
				default:""
			},
			lineHeight:{
				type:[String,null],
				default:""
			},
			borderWidth:{
				type:[String,Number,null],
				default:null
			},
			//默认状态显示的图标
			defaultIcon:{
				type:[String,null],
				default:""
			},
			//完成状态显示的图标
			doneIcon:{
				type:[String,null],
				default:""
			},
			//当前状态显示的图标
			currentIcon:{
				type:[String,null],
				default:""
			},
			//步骤点尺寸，以2em尺寸进行放大，。单位为数字*100%。
			pointSize:{
				type:[Number,null],
				default:0
			},
		},
		data(){
			return {
				inList:[],
				currStep:0,
			}
		},
		computed:{
			setting(){
				return {
					maxItem:4,	//水平最大步骤数量，超出将使用滚动条，未超出自动占满整行。超出自动以100%除以maxItem作为步骤宽度
					alignment: this.alignment ||"after",
					radius: this.radius ||"circle",
					defaultType: this.defaultType ||"default",
					currentType: this.currentType ||"primary",
					lineType: this.lineType || this.currentType ||"primary",
					lineBgColor: this.lineBgColor ||"#eee",
					lineHeight: this.lineHeight ||"0.5em",
					borderWidth: this.$api.isDefined(this.borderWidth)?this.borderWidth :1,
					pointSize: this.pointSize ||1.2,
				}
			},
			mainClass(){
				let res ="";
				let setting = this.setting;
				res += this.custom? this.custom +" " :"vi_steps_normal ";
				res += this.vertical? "vi_steps_vertical " : "vi_steps_horizontal ";
				res += this.inList.length >setting.maxItem? "vi_steps_overflow " :"";
				if(["before","after"].includes(setting.alignment)){
					res += `vi_steps_${setting.alignment} `
				}else if(setting.alignment=="across" && !this.vertical){
					res += `vi_steps_across `
				}else{
					res += "vi_steps_after "
				}
				return res
			},
			groupStyle(){
				if(this.vertical || this.custom){
					return ""
				}
				//水平状态
				if(this.inList.length >this.setting.maxItem){
					return `width:${100/this.setting.maxItem}%;`
				}
				return `width:${100/this.inList.length}%;`
			},
			pointStyle(){
				if(this.custom){
					return ""
				}
				let res ={
					"font-size": (this.setting.pointSize)*100 +"%"
				};
				if(this.vertical){
					
				}
				return this.$api.objToStr(res)
			},
			lineStyle(){
				if(this.custom){
					return ""
				}
				let pointSize = this.setting.pointSize,
					dis = pointSize,
					res ={
						"background-color": this.setting.lineBgColor
					},
					type = this.setting.alignment;
				if(!this.vertical){//水平
					switch(type){
						case "after":
							res["top"] = dis +"em";
							break;
						case "before":
							res["bottom"] = dis +"em";
							break;
						case "across":
							res["top"] = dis +2.5 +"em";
							break;
						default:
							res["top"] = dis +"em";
					}
				}else{//垂直
					type = type=="across"? "after" :type;
					res["top"] = dis +0.25 +"em";
					if(type=="before"){
						res["right"] = dis +0.5 +"em";
					}else{
						res["left"] = dis +0.5 +"em";
					}
				}
				return this.$api.objToStr(res)
			}
		},
		methods:{
			//下一步
			next(){
				if(this.inList.length -1 > this.currStep){
					this.currStep += 1;
					this.updateList();
					this.$emit("input", this.currStep);
				}else{
					console.error("next无效，步骤已结束");
				}
			},
			//上一步
			prev(){
				if(this.currStep >0){
					this.currStep -= 1;
					this.updateList();
					this.$emit("input", this.currStep);
				}else{
					console.error("prev无效，已到起始步骤");
				}
			},
			//跳到某步骤，从0开始
			set(val){
				val = Number(val);
				if(isNaN(val)){
					return
				}
				if(val > this.inList.length -1){
					this.currStep = this.inList.length -1
				}else if(val<0){
					this.currStep =0
				}else{
					this.currStep =val
				}
				this.updateList();
				this.$emit("input", this.currStep);
			},
			//刷新列表状态
			updateList(){
				//根据当前步骤设置
				let list = this.inList,
					currIdx = this.currStep,
					setting = this.setting;
				
				for(let i=0,len=list.length; i<len; i++){
					let step = list[i];
					Object.assign(step, {
						_radius: setting.radius,
						_titleBold: !!this.titleBold,
						_plain: !!this.plain,
						_showType: "",
						_icon: ""
					})
					if(i<currIdx){//已经过步骤
						Object.assign(step, {
							_state:"done",
							_type: setting.currentType,
							_color: this.currentColor ||"",
							_textColor: this.currentTextColor ||"",
							_titleColor: this.currentTitleColor ||"",
							_describeColor: this.currentDescribeColor ||"",
						})
						if(step.doneIcon){
							Object.assign(step, {
								_showType: "icon",
								_icon: step.doneIcon,
							})
						}
					}else if(i==currIdx){//当前步骤
						Object.assign(step, {
							_state: "curr",
							_type: setting.currentType,
							_color: this.currentColor ||"",
							_textColor: this.currentTextColor ||"",
							_titleColor: this.currentTitleColor ||"",
							_describeColor: this.currentDescribeColor ||"",
						})
						if(step.currentIcon){
							Object.assign(step, {
								_showType: "icon",
								_icon: step.currentIcon,
							})
						}
					}else{//后续步骤
						Object.assign(step, {
							_state: "follow",
							_type: setting.defaultType,
							_color: this.defaultColor ||"",
							_textColor: this.defaultTextColor ||"",
							_titleColor: this.defaultTitleColor ||"",
							_describeColor: this.defaultDescribeColor ||"",
						})
						if(step.icon){
							Object.assign(step, {
								_showType: "icon",
								_icon: step.icon,
							})
						}
					}
				}
				this.$forceUpdate();
			}
		},
		watch:{
			"dataList":{
				immediate:true,
				handler(newVal){
					//校验格式
					this.inList = this.$api.clone(newVal ||[]);
					let list = this.inList;
					for(let i=0,len=list.length; i<len; i++){
						let step = list[i];
						if(!this.$api.isValue(step.index)){
							step["index"] =i+1
						}
						if(!step.defaultIcon){
							step["defaultIcon"] = this.defaultIcon ||""
						}
						if(!step.currentIcon){
							step["currentIcon"] = this.currentIcon ||""
						}
						if(!step.doneIcon){
							step["doneIcon"] = this.doneIcon ||""
						}
						if(step.current){//当前步骤
							this.currStep =i;
							this.$emit("input", i)
						}
					}
					this.updateList();
				}
			},
			"value":{
				immediate:true,
				handler(newVal){
					this.currStep = Number(newVal) ||0;
					this.updateList();
				}
			}
		}
	}
</script>

<style lang="scss">
.vi_steps_scroll{
	width: 100%;
}
.vi_steps{
	width: 100%;
	display: flex;
	.vi_steps_group{
		flex-shrink: 0;
		position: relative;
	}
	&.vi_steps_vertical{
		flex-direction: column;
	}
}
//默认类型
.vi_steps_normal{
	.vi_steps_group{
		display: flex;
		flex-direction: column;
		.vi_steps_point{
			position: relative;
			z-index: 1;
			display: flex;
			align-items: center;
			justify-content: center;
		}
		.vi_steps_point_icon,
		.vi_steps_point_text{
			position: relative;
		}
		.vi_steps_point_iconUp,
		.vi_steps_point_textUp{
			position: absolute;
			left: 0;
			top: 0;
		}
		.vi_steps_title{
			line-height: 2;
		}
		.vi_steps_describe{
			font-size: 85%;
			color: #999;
		}
		.vi_steps_title,
		.vi_steps_describe{
			padding: 0 0.5em;
			overflow: hidden;white-space: nowrap;text-overflow: ellipsis;
		}
		.vi_steps_line{
			position: absolute;
			z-index: 0;
		}
		&:last-child .vi_steps_line{
			display: none;
		}
	}
	// 水平模式
	&.vi_steps_horizontal{
		.vi_steps_group{
			.vi_steps_line{
				left:50%;
				width: 100%;
				transform: translateY(-50%);
			}
		}
		&.vi_steps_after{
			.vi_steps_title{
				margin-top: 0.5em;
			}
		}
		&.vi_steps_before{
			.vi_steps_title{
				margin-bottom: 0.5em;
			}
			.vi_steps_group{
				.vi_steps_point{ order: 3; }
				.vi_steps_title{ order: 2; }
				.vi_steps_describe{ order: 1; }
				.vi_steps_line{
					transform: translateY(50%);
				}
			}
		}
		&.vi_steps_across{
			.vi_steps_title{
				margin-bottom: 0.5em;
			}
			.vi_steps_describe{
				margin-top: 1em;
			}
			.vi_steps_group{
				.vi_steps_point{ order: 2; }
				.vi_steps_title{ order: 1; }
				.vi_steps_describe{ order: 3; }
			}
		}
	}
	// 垂直模式
	&.vi_steps_vertical{
		.vi_steps_group{
			display: block;
			.vi_steps_title{
				white-space: normal;
			}
			.vi_steps_describe{
				white-space: normal;
			}
			.vi_steps_line{
				height:100%;
				transform: translateX(-50%);
			}
		}
		&.vi_steps_after{
			.vi_steps_group{
				padding: 0.5em 0 0.5em 0.5em;
			}
			.vi_steps_point{
				float: left;
				padding: 0.25em 0;
			}
			.vi_steps_title{
				padding-left: 1em;
			}
			.vi_steps_describe{
				padding-left: 1em;
			}
		}
		&.vi_steps_before{
			.vi_steps_group{
				padding: 0.5em 0.5em 0.5em 0;
			}
			.vi_steps_point{
				float: right;
				padding: 0.25em 0;
			}
			.vi_steps_title{
				padding-right: 1em;
				display: flex;
				justify-content: flex-end;
			}
			.vi_steps_describe{
				padding-right: 1em;
				display: flex;
				justify-content: flex-end;
			}
			.vi_steps_line{
				transform: translateX(50%);
			}
		}
	}
}
.vi_bold{
	font-weight: bold;
}

@import "./custom.scss";
</style>